<script lang="tsx">
/**
 * 树形页面
 */
export default {
  name: "page-tree"
}
</script>

<script lang="tsx" setup>
import TreeForm from "../../components/business/tree-form/index.vue"
import {nextTick, ref, watch} from "vue"
import PageTreeManager from "./page-tree-manager.ts"
import {processRequest} from "../../index.ts"
import ProgramForm from "../../components/business/program-form/index.vue"
import SearchForm from "../../components/business/search-form/index.vue"

/**
 * 定义props
 */
const props = defineProps<{
  config: PageTreeManager<any>,
  reflections?: any
}>()

/**
 * 定义emit
 */
const emit = defineEmits<{
  (e: "submit", node: any[]): void
}>()

/**
 * 树型实例
 */
const treeFormRef = ref()
const searchFormRef = ref()
const programFormRef = ref()

/**
 * 页面数据
 */
const treeData = ref()

/**
 * 获取数据
 */
const refreshTreeData = async () => {
  const searchData = await searchFormRef.value.getSearchFormData()
  const result = await processRequest.get(treeData.value.url, {
    ...searchData
  })
  if (treeData.value.getDataCallBack) {
    treeData.value.tree.data = await treeData.value.getDataCallBack(result)
  } else {
    treeData.value.tree.data = result
  }
}

/**
 * 提交数据
 */
const handleSubmit = () => {
  const treeData = getTreeData()
  emit("submit", treeData.value)
}

/**
 * 获取搜索框数据
 */
const getSearchFormData = () => {
  return searchFormRef.value.getSearchFormData()
}

/**
 * 设置搜索框数据
 */
const setSearchFormData = (data: any) => {
  searchFormRef.value.setSearchFormData(data)
}

/**
 * 获取树型数据
 */
const getTreeData = () => {
  return treeFormRef.value.getTreeData()
}

/**
 * 设置树型数据
 */
const setTreeData = (data: any) => {
  treeFormRef.value.setTreeData(data)
}

/**
 * 获取当前选中的节点
 */
const getCurrentNode = () => {
  return treeFormRef.value.getCurrentNode()
}

/**
 * 底部渲染
 */
const bottomRenderFn = () => {
  if (props.config.bottom?.renderFn) {
    return props.config.bottom.renderFn(treeData.value)
  } else {
    return
  }
}

/**
 * 监听
 */
watch(() => props.config, (newValue: any) => {
  if (newValue) {
    treeData.value = newValue
    if (newValue.url) {
      nextTick(() => {
        refreshTreeData()
      })
    }
  }
}, {
  deep: true,
  immediate: true
})

/**
 * 暴露
 */
defineExpose({
  getTreeData,
  setTreeData,
  refreshTreeData,
  getSearchFormData,
  setSearchFormData,
  getCurrentNode
})
</script>

<template>
  <div class="page-tree">
    <div v-if="treeData.title" class="page-tree-header">
      <div class="page-tree-title">
        {{ treeData.title }}
      </div>
    </div>
    <div v-if="config?.searchForm" class="search-form">
      <slot name="search-form">
        <SearchForm ref="searchFormRef" :reflections="props?.reflections" :searchFormModel="config?.searchForm"
                    v-bind="$attrs" @refreshTableData="refreshTreeData" @searchFormReset="refreshTreeData"
                    @searchFormFilter="refreshTreeData"/>
      </slot>
    </div>
    <div v-if="config?.programForm" class="program-form">
      <slot name="program-form">
        <ProgramForm ref="programFormRef" :programFormModel="config?.programForm" v-bind="$attrs"/>
      </slot>
    </div>
    <div class="page-tree-body">
      <el-scrollbar>
        <div class="body-logout">
          <TreeForm ref="treeFormRef" :tree="treeData?.tree" v-bind="$attrs"/>
        </div>
      </el-scrollbar>
    </div>
    <div v-if="config?.bottom?.show" class="page-tree-bottom">
      <div v-if="!config?.bottom?.renderFn" class="page-tree-bottom-logout">
        <el-button @click="refreshTreeData">刷新</el-button>
        <el-button type="primary" @click="handleSubmit">提交</el-button>
      </div>
      <bottomRenderFn v-else :render="config?.bottom?.renderFn"/>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.page-tree {
  flex: 1;
  padding: 20px;
  background-color: #ffffff;
  border-radius: 10px;
  display: flex;
  flex-direction: column;

  .page-tree-header {
    flex: 0;

    .page-tree-title {
      font-size: 18px;
      color: #333333;
      margin-bottom: 5px;
      font-weight: bold;
    }
  }

  .search-form {
    flex: 0;
  }

  .program-form {
    flex: 0;
  }

  .page-tree-body {
    margin-top: 10px;
    flex: 1;

    .body-logout {
      height: 0;
    }
  }

  .page-tree-bottom {
    text-align: center;
    margin-top: 20px;
    flex: 0;
  }
}
</style>